/* $Id: CallActivity.java 5138 2015-07-30 06:23:35Z ming $ */
/*
 * Copyright (C) 2013 Teluu Inc. (http://www.teluu.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package com.cloudptt.wp.ui.call.single;

import android.app.Activity;
import android.app.FragmentTransaction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.cloudptt.api.comm.CommDlg;
import com.cloudptt.api.pjsip.api.SipManager;
import com.cloudptt.api.pjsip.service.AppRTCAudioManager;
import com.cloudptt.api.product.ISuperCallOperator;
import com.cloudptt.api.product.Product;
import com.cloudptt.api.product.config.call.AnswerModeConfig;
import com.cloudptt.api.product.func.call.CallAttr;
import com.cloudptt.api.product.func.call.CallConst;
import com.cloudptt.api.product.func.call.CallListener;
import com.cloudptt.api.product.func.call.group.fsm.video.GroupCallMemberInfo;
import com.cloudptt.api.product.func.call.single.LaunchCallInfo;
import com.cloudptt.api.product.log.Log;
import com.cloudptt.api.product.operator.CallOperator;
import com.cloudptt.wp.R;
import com.cloudptt.wp.SysApplication;
import com.cloudptt.wp.ui.call.VideoCallOp;
import com.cloudptt.wp.ui.call.single.fv.FloatWindowService;
import com.mcptt.config.model.McpttLoginInfo;
import com.mcptt.db.model.AddrInfo;

import java.util.List;


public class CallActivity extends Activity
        implements CallListener, VideoCallOp, CallFragment.OnCallEvents, View.OnClickListener {
    private Product product = null;
    private LaunchCallInfo callInfo = null;
    private String curCallKey = null;
    private AddrInfo fromAddressInfo = null;
    private CallFragment callFragment;
    private ImageView minimizeIv = null;
    private TextView tipTextView = null;
    private TextView timerTV = null;

//    private VideoSurfaceHandler previewHandler = null;
    private SurfaceView surfaceInVideo = null;
    private SurfaceView surfacePreview = null;

    private boolean isShowAlready = false;
    private BroadcastReceiver homeReceiver = null;
    private boolean isReceiverRegistered = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call);
//        if (product == null) {
//            SysApplication app = ((SysApplication) getApplicationContext());
//            product = app.getProduct();
//            product.setSingleCallListener(this);
//        }

        callInfo = (LaunchCallInfo) getIntent().getSerializableExtra(SipManager.EXTRA_PRIVACY_CALL_INFO);
        curCallKey = callInfo.getCallKey();
        fromAddressInfo = (AddrInfo) getIntent().getSerializableExtra(SipManager.EXTRA_PRIVACY_CALL_USER);
        Log.debug(this.getClass(),"onCreate callInfo = " + callInfo + " fromAddressInfo = " + fromAddressInfo);

        callFragment = new CallFragment(callInfo);
        callFragment.setArguments(getIntent().getExtras());

        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.add(R.id.call_fragment_container, callFragment);
        ft.commit();

        tipTextView = (TextView)
                findViewById(R.id.tipTextView);
        timerTV = (TextView)
                findViewById(R.id.timerTV);
        minimizeIv = (ImageView)
                findViewById(R.id.minimizeIv);
        minimizeIv.setOnClickListener(this);
        surfaceInVideo = (SurfaceView)
                findViewById(R.id.surfaceInVideo);
        surfacePreview = (SurfaceView)
                findViewById(R.id.surfacePreview);

        if(callInfo.isHasVideo())
        {
            surfaceInVideo.setZOrderMediaOverlay(true);
            
            int callType = callInfo.getCallType();
//            if (CallAttr.isPrivateCall(callType)) {
                if((callInfo.isMoCall() && CallAttr.isPushCall(callType))
                    || (!callInfo.isMoCall() && CallAttr.isPullCall(callType)))
                {
                    setSurfaceView(surfacePreview,surfaceInVideo);
                    surfacePreview.setVisibility(View.GONE);
                    surfaceInVideo.setVisibility(View.VISIBLE);
                }
                else if((callInfo.isMoCall() && CallAttr.isPullCall(callType))
                        || (!callInfo.isMoCall() && CallAttr.isPushCall(callType)))
                {
                    setSurfaceView(surfaceInVideo, surfacePreview);
                    surfacePreview.setVisibility(View.GONE);
                    surfaceInVideo.setVisibility(View.VISIBLE);
                }
                else {
                    surfacePreview.setZOrderMediaOverlay(true);
                    surfacePreview.setZOrderOnTop(true);
                    surfaceInVideo.setVisibility(View.VISIBLE);
                    surfacePreview.setVisibility(View.VISIBLE);
                    setSurfaceView(surfaceInVideo, surfacePreview);
                }
//            }
        }
        else
        {
            surfaceInVideo.setVisibility(View.GONE);
            surfacePreview.setVisibility(View.GONE);
        }

        TextView nameTv  = (TextView) findViewById(R.id.textViewPeer);
        if(fromAddressInfo != null)
        {
            String dscp = fromAddressInfo.getDscp();
            if(callInfo.isEmergency())
            {
                dscp = getString(R.string.title_emergency) + dscp;
                nameTv.setTextColor(Color.RED);
            }
            nameTv.setText(dscp);
        }

        TextView selfTv = (TextView)findViewById(R.id.selfTv);
        if (product == null) {
            SysApplication app = ((SysApplication) getApplicationContext());
            product = app.getProduct();
        }
        if (product != null) {
            McpttLoginInfo loginInfo = product.getMcpttLoginInfo();
            Log.debug(this.getClass(), "onCreate loginInfo = " + loginInfo);
            if(loginInfo != null) {
                String str = loginInfo.getMcIdInfo().getDscp();
                Log.debug(this.getClass(), "onCreate str = " + str);
                selfTv.setText(str);
            }
        }
        registerHomeKeyReceiver();
    }

    @Override
    protected void onResume() {
        super.onResume();
        boolean isActive = isActiveCall();
        Log.debug(this.getClass(), "onResume isActive = " + isActive);
        if(!isActive)
        {
            updateUiByCallState(CallConst.CallState_InitState);
        }
        else
        {
            updateCallState(curCallKey,callInfo.getCallState(),callInfo.isHasVideo());
            updateMediaStatus(curCallKey,callInfo.getCallMediaState());
            setListener();
        }
        checkAutoAccept();
    }
    private void checkAutoAccept()
    {
        Log.debug(this.getClass(), "checkAutoAccept");
        if (product == null) {
            SysApplication app = ((SysApplication) getApplicationContext());
            product = app.getProduct();
        }
        Log.debug(this.getClass(), "checkAutoAccept 1");
        if (product != null) {
            AnswerModeConfig answerModeConfig = product.getSysConfig().getAnswerModeConfig();
            Log.debug(this.getClass(), "checkAutoAccept answerModeConfig = " + answerModeConfig);
            if(answerModeConfig != null)
            {
                if(callInfo != null)
                {
                    Log.debug(this.getClass(), "checkAutoAccept callInfo.isHasVideo() = " + callInfo.isHasVideo());
                    if (!callInfo.isHasVideo()
                            && answerModeConfig.isAutoAnswerVoice())
                    {
                        acceptCall();
                    }
                    else if (callInfo.isHasVideo()
                            && answerModeConfig.isAutoAnswerVideo())
                    {
                        acceptCall();
                    }
                    else
                    {
                        Log.debug(this.getClass(), "checkAutoAccept callInfo = null");
                    }
                }
                else
                {
                    Log.debug(this.getClass(), "checkAutoAccept callInfo = null");
                }
            }
            else
            {
                Log.debug(this.getClass(), "checkAutoAccept answerModeConfig = null");
            }
        }
        else
        {
            Log.debug(this.getClass(), "checkAutoAccept product = null");
        }
    }

    private void setListener() {
        if (product == null) {
            SysApplication app = ((SysApplication) getApplicationContext());
            product = app.getProduct();
        }
        if (product == null) {
            Log.debug(this.getClass(), "onCreate product == null");
        }
        if (product != null) {
            product.setSingleCallListener(this);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.debug(this.getClass(), "onDestroy ");
        if (isReceiverRegistered) {
            try {
                unregisterReceiver(homeReceiver);
                isReceiverRegistered = false;
            } catch (IllegalArgumentException e) {
                // 如果已经注销，忽略异常
                Log.debug(this.getClass(), "Receiver not registered" + e);
            }
        }
    }

//    @Override
//    public void incomingCall(String callKey,AddrInfo incomingInfo)
//    {}
    @Override
    public void updateCallState(String callKey, int callState,boolean isHasVideo) {
        Log.debug(this.getClass(),"updateCallState callKey = " + callKey + " callState = " + callState);
        if(callState == CallConst.CallState_InitState
                || callState == CallConst.CallState_DisconnectingState)
        {
            Log.debug(this.getClass(), "updateUiByCallState finish" );
            clearAndCloseSelf();
            finish();
        }
        this.callInfo.setCallState(callState);
        if(callFragment != null)
        {
            callFragment.setCallState(callInfo);
        }
        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                updateUiByCallState(callState);
            }
        });


    }

    private void updateUiByCallState(int callState)
    {
        Log.debug(this.getClass(), "updateUiByCallState callState = " + callState);

        if (CallConst.CallState_InitState == callState)
        {
            if(surfacePreview != null)
            {
                surfacePreview.destroyDrawingCache();
//                smallSurView = null;
            }
            if(surfaceInVideo != null)
            {
                surfaceInVideo.destroyDrawingCache();
//                smallSurView = null;
            }
//            if(previewHandler != null)
//            {
//                previewHandler.updateVideoPreview(null);
//                //previewHandler.surfaceDestroyed(null);
////                previewHandler = null;
//            }
            if(product == null)
            {
                SysApplication app = ((SysApplication) getApplicationContext());
                product = app.getProduct();
            }
            product.setSingleCallListener(null);
            setResult(RESULT_OK);
            this.product = null;
            finish();
        }
        else if (CallConst.CallState_ConnectingState == callState)
        {
            int callDir = this.callInfo.getCallDir();
            if(callInfo.isMoCall())
            {
				tipTextView.setText(R.string.single_call_conncting_mo);
            }
            else
            {
                String str =getCallTypeDesc(callInfo.getCallType(), callInfo.isHasVideo());
                String tipStr = getString(R.string.single_call_conncting_mt, str);
				tipTextView.setText(tipStr);
            }
        }
        else if(CallConst.CallState_Activite == callState)
        {
            String str =getCallTypeDesc(callInfo.getCallType(), callInfo.isHasVideo());
            String tipStr = getString(R.string.single_call_conncted, str);
            tipTextView.setText(tipStr);
        }
    }

    private String getCallTypeDesc(int type,boolean hasVideo)
    {
        if(type == CallAttr.CallType_Pull_One_To_One
            || type == CallAttr.CallType_Pull_One_To_Svr)
        {
            return this.getString(R.string.single_call_video_pull);
        }
        else if(type == CallAttr.CallType_Push_One_To_One
                || type == CallAttr.CallType_Push_One_To_Svr)
        {
            return this.getString(R.string.single_call_video_push);
        }
        else
        {
            if(!hasVideo)
            {
                return this.getString(R.string.single_call_voice);
            }
            else
            {
                return this.getString(R.string.single_call_video);
            }
        }
    }

    @Override
    public void notifyErrStr(String callKey, String errStr) {

    }

    @Override
    public void updateCallDuration(String callKey, String secStr) {
        timerTV.setText(secStr);
    }

    @Override
    public void updateMicMute(String callKey, boolean isMicMute) {

    }

    @Override
    public void updateMediaStatus(String callKey, int mediaStatus)
    {
        this.callInfo.setCallMediaState(mediaStatus);
        Log.debug(this.getClass(),"updateMediaStatus mediaStatus = " + mediaStatus);

        if(surfacePreview != null)
        {
            surfacePreview.setZOrderMediaOverlay(true);
            surfacePreview.setZOrderOnTop(true);
            surfacePreview.bringToFront();
        }
    }
    @Override
    public void updateVideoEvent(String callKey)
    {
        Log.debug(this.getClass(),"updateVideoEvent callKey = " + callKey);
        if(surfacePreview != null)
        {
            surfacePreview.setZOrderMediaOverlay(true);
            surfacePreview.setZOrderOnTop(true);
            surfacePreview.bringToFront();
        }
    }
    @Override
    public void updateGroupCallMemberInfoList(List<GroupCallMemberInfo> groupCallMemberInfoList)
    {}


public boolean isActiveCall() {
    Log.debug(this.getClass(),"isActiveCall");
    if (product == null) {
        SysApplication app = ((SysApplication) getApplicationContext());
        product = app.getProduct();
    }
    if (product != null) {
        ISuperCallOperator op = product.getSuperCallOperator();
        return op.isActiveCall(curCallKey);
    }
    return false;
}
    @Override
    public void setSurfaceView(SurfaceView surfaceInVideo, SurfaceView surfacePreview) {
        Log.debug(this.getClass(),"setSurfaceView");
        if(!callInfo.isHasVideo())
        {
            return;
        }
        if (product == null) {
            SysApplication app = ((SysApplication) getApplicationContext());
            product = app.getProduct();
        }
        if (product != null) {
            ISuperCallOperator op = product.getSuperCallOperator();
            String callIdStr = callInfo.getCallIdStr();
            op.getCallOperator().setSurfaceView(callIdStr,surfaceInVideo,surfacePreview);
        }
    }
    @Override
    public void setCaptureOrient(int orient)
    {
        Log.debug(this.getClass(),"setCaptureOrient");
        if(!callInfo.isHasVideo())
        {
            return;
        }
        if (product == null) {
            SysApplication app = ((SysApplication) getApplicationContext());
            product = app.getProduct();
        }
        if (product != null) {
            ISuperCallOperator op = product.getSuperCallOperator();
            op.getCallOperator().setCaptureOrient(orient);
        }
    }

    private void startFloatWindow() {
        com.cloudptt.api.product.log.Log.debug(this.getClass(), "startFloatWindow");
        Intent intent = new Intent();
        intent.putExtra(SipManager.EXTRA_PRIVACY_CALL_INFO, callInfo);
        intent.putExtra(SipManager.EXTRA_PRIVACY_CALL_USER, fromAddressInfo);
        com.cloudptt.api.product.log.Log.debug(this.getClass(), "startFloatWindow callInfo.isHasVideo() = " + callInfo.isHasVideo());
        intent.setClass(CallActivity.this, FloatWindowService.class);
        startService(intent);
    }

    public void acceptCall() {
        Log.debug(this.getClass(), "acceptCall");
        if (product == null) {
            SysApplication app = ((SysApplication) getApplicationContext());
            product = app.getProduct();
        }
        if (product != null) {
            ISuperCallOperator op = product.getSuperCallOperator();
            op.doUserAction(curCallKey, CallConst.BtnAction_Answer,"");
        }
    }

    public void hangupCall() {
        Log.debug(this.getClass(), "hangupCall");
        if (product == null) {
            SysApplication app = ((SysApplication) getApplicationContext());
            product = app.getProduct();
        }
        if (product != null) {
            ISuperCallOperator op = product.getSuperCallOperator();
            op.doUserAction(curCallKey, CallConst.BtnAction_Hangup,"");
        }
        //finish();
    }

    public void onCameraSwitch()
    {
//        surfacePreview.setVisibility(View.VISIBLE);
    }

    public boolean setSpeakerphoneEnable(boolean enable) {
        Log.debug(this.getClass(), "setSpeakerphoneOn enable = " + enable);
        if (product == null) {
            SysApplication app = ((SysApplication) getApplicationContext());
            product = app.getProduct();
        }
        if (product != null) {
            ISuperCallOperator op = product.getSuperCallOperator();
            return op.setSpeakerphoneEnable(curCallKey,enable);
        }
        return enable;
    }

    public boolean setMicrophoneEnable(boolean enable) {
        Log.debug(this.getClass(), "setMicrophoneMute enable = " + enable);
        if (product == null) {
            SysApplication app = ((SysApplication) getApplicationContext());
            product = app.getProduct();
        }
        if (product != null) {
            ISuperCallOperator op = product.getSuperCallOperator();
            return op.setMicrophoneEnable(curCallKey,enable);
        }
        return enable;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub
        if (product == null) {
            SysApplication app = ((SysApplication) getApplicationContext());
            product = app.getProduct();
        }
        CallOperator op = product.getSuperCallOperator().getCallOperator();

        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
//                showFloatingWindow();
                break;
            case KeyEvent.KEYCODE_VOLUME_UP:
                op.onVol(AppRTCAudioManager.Vol_Type_Up);
                break;
            case KeyEvent.KEYCODE_VOLUME_DOWN:
                op.onVol(AppRTCAudioManager.Vol_Type_Down);
                break;
            case KeyEvent.KEYCODE_VOLUME_MUTE:
                break;
        }
        return super.onKeyDown(keyCode, event);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.minimizeIv:
                Log.debug(this.getClass(), "click minimizeIv");
//                showFloatingWindow();
                break;

            default:
                break;
        }
    }
    private void showFloatingWindow() {
        Log.debug(this.getClass(), "isShowAlready = " + isShowAlready);

        if (!checkFloatPermission(this)) {
            String str = this.getResources().getString(R.string.permission_suspension);
            CommDlg.show(this, str);
            startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), 0);
        } else {
            if(product != null) {
                product.setShowFloatWin(curCallKey, true);
            }
            clearAndCloseSelf();
            startFloatWindow();
            isShowAlready = true;
        }
    }

    private boolean checkFloatPermission(Context context) {
        if (Build.VERSION.SDK_INT >= 23) {
            boolean result = false;
            result = Settings.canDrawOverlays(context);
            return result;
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//4.4-5.1
            return true;
        }
        return true;
    }


    private void clearAndCloseSelf()
    {
        Log.debug(this.getClass(), "clearAndCloseSelf");
//        if(surfaceInVideo != null)
//        {
//            surfaceInVideo.getHolder().addCallback(null);
//        }
//        if(previewHandler != null)
//        {
//            previewHandler.updateVideoPreview(null);
//        }
//        if(surfacePreview != null)
//        {
//            surfacePreview.getHolder().addCallback(null);
//            surfacePreview.destroyDrawingCache();
//            surfacePreview = null;
//        }
//        previewHandler = null;
        if(product != null) {
            product.setSingleCallListener(null);
            setResult(RESULT_OK);
            this.product = null;
        }
        finish();
    }
    private void registerHomeKeyReceiver() {
        IntentFilter homeFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        homeReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String reason = intent.getStringExtra("reason");
                Log.debug(this.getClass(), "reason = " + reason);
                if ("homekey".equals(reason)) {
                    // 当HOME键被按下时，显示悬浮窗
//                    showFloatingWindow();
                }
            }
        };
        registerReceiver(homeReceiver, homeFilter);
        isReceiverRegistered = true;
    }
}
